package priv.lhy.log.core;

import com.fasterxml.jackson.databind.json.JsonMapper;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import priv.lhy.log.entity.RequestInfo;
import priv.lhy.log.entity.ResponseInfo;
import priv.lhy.log.util.MethodInvocationUtil;

import javax.servlet.http.HttpServletRequest;

/**
 * @author : lihy
 * @date : 2021/8/5 10:33
 */
@Slf4j
public class WebLogAdvice implements MethodInterceptor {

    private final JsonMapper jsonMapper = new JsonMapper();

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        long start = System.currentTimeMillis();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        RequestInfo requestInfo = new RequestInfo();
        requestInfo.setToken(request.getHeader("X-Token"));
        requestInfo.setIp(request.getRemoteAddr());
        requestInfo.setUrl(request.getRequestURL().toString());
        requestInfo.setHttpMethod(request.getMethod());
        requestInfo.setClassMethod(String.format("%s.%s", invocation.getMethod().getDeclaringClass().getName(),
                invocation.getMethod().getName()));
        if (invocation.getMethod().getParameters().length > 0) {
            requestInfo.setRequestParams(jsonMapper
                    .writeValueAsString(MethodInvocationUtil.getParamsByInvocation(invocation)));
        }
        log.info("Web Request Info      : {}", requestInfo.toString());

        Object result = invocation.proceed();

        ResponseInfo responseInfo = new ResponseInfo();
        responseInfo.setHttpMethod(request.getMethod());
        responseInfo.setClassMethod(String.format("%s.%s", invocation.getMethod().getDeclaringClass().getName(),
                invocation.getMethod().getName()));
        responseInfo.setTimeCost(System.currentTimeMillis() - start);
        responseInfo.setResult(result);
        log.info("Web response Info      : {}", responseInfo.toString());

        return result;
    }


}
